home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  8.0 KB  |  422 lines

  1. /*
  2. **    Memory.c
  3. **
  4. **    Memory management routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     // Main memory pool puddle size
  15.  
  16. #define PUDDLE_SIZE 32768
  17.  
  18.     // Memory allocation data
  19.  
  20. STATIC struct SignalSemaphore    MemorySemaphore;
  21. STATIC APTR            MemoryPool;
  22.  
  23.     // Diagnostic data
  24.  
  25. typedef char (* __asm SegTrack(REG(a0) ULONG Address,REG(a1) ULONG *SegNum,REG(a2) ULONG *Offset));
  26.  
  27. struct SegSem
  28. {
  29.     struct SignalSemaphore     seg_Semaphore;
  30.     SegTrack        *seg_Find;
  31. };
  32.  
  33. struct FirewallInfo
  34. {
  35.     ULONG            Checksum;
  36.  
  37.     ULONG            Address;
  38.     ULONG            TotalSize;
  39.     ULONG            ReturnAddress;
  40.     ULONG            Size;
  41.     ULONG            FillByte;
  42.  
  43.     ULONG            FirePre;
  44.     ULONG            FirePost;
  45. };
  46.  
  47. STATIC LONG            FirewallPre = 0,FirewallPost = 0;
  48. STATIC ULONG            FillByte = 1;
  49.  
  50. STATIC LONG            Smallest = -1,Largest = -1;
  51.  
  52.     /* MemorySetup():
  53.      *
  54.      *    Set up the main memory pool.
  55.      */
  56.  
  57. BOOL
  58. MemorySetup()
  59. {
  60.     BOOL DosOpen = FALSE;
  61.  
  62.     if(!DOSBase)
  63.     {
  64.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  65.             DosOpen = TRUE;
  66.     }
  67.  
  68.     if(DOSBase)
  69.     {
  70.         UBYTE LocalBuffer[256];
  71.  
  72.         if(GetVar("TERMPREALLOC",LocalBuffer,256,NULL) > 0)
  73.         {
  74.             if(StrToLong(LocalBuffer,&FirewallPre) > 0)
  75.             {
  76.                 if(FirewallPre < 16)
  77.                     FirewallPre = 16;
  78.  
  79.                 FirewallPost = 16;
  80.  
  81.                 if(GetVar("TERMPOSTALLOC",LocalBuffer,256,NULL) > 0)
  82.                 {
  83.                     if(StrToLong(LocalBuffer,&FirewallPre) <= 0)
  84.                         FirewallPost = 16;
  85.                 }
  86.  
  87.                 FirewallPre    = (FirewallPre + 15) & ~15;
  88.                 FirewallPost    = (FirewallPost + 15) & ~15;
  89.  
  90.                 if(!FirewallPost)
  91.                     FirewallPost = 16;
  92.             }
  93.             else
  94.                 FirewallPost = 0;
  95.         }
  96.  
  97.         if(DosOpen)
  98.         {
  99.             CloseLibrary((struct Library *)DOSBase);
  100.             DOSBase = NULL;
  101.         }
  102.     }
  103.  
  104.     InitSemaphore(&MemorySemaphore);
  105.  
  106.     if(MemoryPool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY,PUDDLE_SIZE,PUDDLE_SIZE,SysBase))
  107.         return(TRUE);
  108.     else
  109.         return(FALSE);
  110. }
  111.  
  112.     /* MemoryCleanup():
  113.      *
  114.      *    Clean up the main memory pool.
  115.      */
  116.  
  117. VOID
  118. MemoryCleanup()
  119. {
  120.     if(Smallest != -1)
  121.     {
  122.         DB(kprintf("term stats: smallest allocation was %ld bytes\n",Smallest));
  123.         Smallest = -1;
  124.     }
  125.  
  126.     if(Largest != -1)
  127.     {
  128.         DB(kprintf("term stats: largest allocation was %ld bytes\n",Largest));
  129.         Largest = -1;
  130.     }
  131.  
  132.     if(MemoryPool)
  133.     {
  134.         AsmDeletePool(MemoryPool,SysBase);
  135.  
  136.         MemoryPool = NULL;
  137.     }
  138. }
  139.  
  140.     /* FreeVecPooled(APTR Memory):
  141.      *
  142.      *    Free a memory chunk.
  143.      */
  144.  
  145. VOID __asm
  146. FreeVecPooledLocal(REG(a0) APTR Memory,REG(a1) ULONG ReturnAddress)
  147. {
  148.     if(Memory && MemoryPool)
  149.     {
  150.         ULONG *Data = (ULONG *)Memory;
  151.  
  152.         ObtainSemaphore(&MemorySemaphore);
  153.  
  154.         if(FirewallPre)
  155.         {
  156.             struct FirewallInfo *Info;
  157.             ULONG Sum,*Thing;
  158.             LONG i;
  159.  
  160.             Info = (struct FirewallInfo *)(((ULONG)Memory) - (sizeof(struct FirewallInfo) + FirewallPre));
  161.  
  162.             for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
  163.                 Sum += Thing[i];
  164.  
  165.             if(Info -> Checksum == ~Sum && Memory == (APTR)Info -> Address)
  166.             {
  167.                 UBYTE *Data;
  168.                 LONG i,TotalSize;
  169.                 BOOL AllocationProblem = FALSE;
  170.  
  171.                 Data = (UBYTE *)Info -> FirePre;
  172.  
  173.                 for(i = 0 ; i < FirewallPre ; i++)
  174.                 {
  175.                     if(Data[i] != Info -> FillByte)
  176.                     {
  177.                         LONG j;
  178.  
  179.                         AllocationProblem = TRUE;
  180.  
  181.                         DB(kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed before, FillByte %02lx:",Memory,Info -> Size,FirewallPre - i,Info -> FillByte));
  182.  
  183.                         Data = &Data[i];
  184.  
  185.                         for(j = 0 ; j < FirewallPre - i ; j++)
  186.                         {
  187.                             if(!(j & 7))
  188.                                 DB(kprintf("\n      %08lx: ",&Data[j]));
  189.  
  190.                             DB(kprintf("%02lx ",Data[j]));
  191.                         }
  192.  
  193.                         DB(kprintf("\n"));
  194.  
  195.                         break;
  196.                     }
  197.                 }
  198.  
  199.                 Data = (UBYTE *)Info -> FirePost;
  200.  
  201.                 for(i = FirewallPost - 1 ; i >= 0 ; i--)
  202.                 {
  203.                     if(Data[i] != Info -> FillByte)
  204.                     {
  205.                         LONG j;
  206.  
  207.                         Data = (UBYTE *)Info -> FirePost;
  208.  
  209.                         DB(if(AllocationProblem))
  210.                             DB(kprintf("      %ld bytes trashed after:",i + 1));
  211.                         DB(else)
  212.                             DB(kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed after, FillByte 0x%02lx:",Memory,Info -> Size,i + 1,Info -> FillByte));
  213.  
  214.                         AllocationProblem = TRUE;
  215.  
  216.                         for(j = 0 ; j <= i ; j++)
  217.                         {
  218.                             if(!(j & 7))
  219.                                 DB(kprintf("\n      %08lx: ",&Data[j]));
  220.  
  221.                             DB(kprintf("%02lx ",Data[j]));
  222.                         }
  223.  
  224.                         DB(kprintf("\n"));
  225.  
  226.                         break;
  227.                     }
  228.                 }
  229.  
  230.                 if(AllocationProblem)
  231.                 {
  232.                     struct SegSem *SegTracker;
  233.  
  234.                     Forbid();
  235.  
  236.                     if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
  237.                     {
  238.                         char LocalBuffer[256];
  239.                         ULONG Segment,Offset;
  240.                         char *Name;
  241.  
  242.                         DB(kprintf("\n"));
  243.  
  244.                         if(Name = (*SegTracker -> seg_Find)(Info -> ReturnAddress,&Segment,&Offset))
  245.                         {
  246.                             CopyMem(Name,LocalBuffer,255);
  247.                             LocalBuffer[255] = 0;
  248.  
  249.                             DB(kprintf("      Alloc by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset));
  250.                         }
  251.  
  252.                         if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
  253.                         {
  254.                             CopyMem(Name,LocalBuffer,255);
  255.                             LocalBuffer[255] = 0;
  256.  
  257.                             DB(kprintf("       Free by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset));
  258.                         }
  259.                     }
  260.  
  261.                     Permit();
  262.                 }
  263.  
  264.                     // Let's misbehave...
  265.  
  266.                 TotalSize = Info -> TotalSize;
  267.  
  268.                 memset(Info,0x11,TotalSize);
  269.  
  270.                 AsmFreePooled(MemoryPool,Info,TotalSize,SysBase);
  271.             }
  272.             else
  273.             {
  274.                 struct SegSem *SegTracker;
  275.  
  276.                 Forbid();
  277.  
  278.                 if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
  279.                 {
  280.                     char LocalBuffer[256];
  281.                     ULONG Segment,Offset;
  282.                     char *Name;
  283.  
  284.                     if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
  285.                     {
  286.                         CopyMem(Name,LocalBuffer,255);
  287.                         LocalBuffer[255] = 0;
  288.  
  289.                         DB(kprintf("       Bogus free from 0x%08lx by |%s| %lx:%lx\n",Memory,LocalBuffer,Segment,Offset));
  290.                     }
  291.                 }
  292.  
  293.                 Permit();
  294.             }
  295.         }
  296.         else
  297.             AsmFreePooled(MemoryPool,&Data[-1],Data[-1],SysBase);
  298.  
  299.         ReleaseSemaphore(&MemorySemaphore);
  300.     }
  301. }
  302.  
  303.     /* AllocVecPooled(ULONG Size,ULONG Flags):
  304.      *
  305.      *    Allocate a memory chunk from the main memory pool and
  306.      *    remember its size.
  307.      */
  308.  
  309. APTR __asm
  310. AllocVecPooledLocal(REG(d0) ULONG Size,REG(d1) ULONG Flags,REG(a0) ULONG ReturnAddr)
  311. {
  312.     if(MemoryPool)
  313.     {
  314.         ObtainSemaphore(&MemorySemaphore);
  315.  
  316.         if(FirewallPre)
  317.         {
  318.             struct FirewallInfo *Info;
  319.             ULONG FireSize;
  320.             ULONG RoundSize = (Size + 3) & ~3;
  321.  
  322.             if(Smallest == -1)
  323.                 Smallest = Size;
  324.  
  325.             if(Largest == -1)
  326.                 Largest = Size;
  327.  
  328.             if(Size < Smallest)
  329.                 Smallest = Size;
  330.  
  331.             if(Size > Largest)
  332.                 Largest = Size;
  333.  
  334.             FireSize = sizeof(struct FirewallInfo) + FirewallPre + RoundSize + FirewallPost;
  335.  
  336.             if(Info = (struct FirewallInfo *)AsmAllocPooled(MemoryPool,FireSize,SysBase))
  337.             {
  338.                 ULONG *Data,Sum,*Thing;
  339.                 LONG i;
  340.  
  341.                 Info -> Address        = ((ULONG)Info) + sizeof(struct FirewallInfo) + FirewallPre;
  342.                 Info -> TotalSize    = FireSize;
  343.                 Info -> ReturnAddress    = ReturnAddr;
  344.                 Info -> Size        = Size;
  345.                 Info -> FillByte    = FillByte;
  346.  
  347.                 Info -> FirePre        = (ULONG)&Info[1];
  348.                 Info -> FirePost    = Info -> FirePre + FirewallPre + RoundSize;
  349.  
  350.                 memset((APTR)(Info -> FirePre),FillByte,FirewallPre);
  351.                 memset((APTR)(Info -> FirePost),FillByte,FirewallPost);
  352.  
  353.                 for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
  354.                     Sum += Thing[i];
  355.  
  356.                 Info -> Checksum = ~Sum;
  357.  
  358.                 FillByte = (FillByte + 2) & 0xFF;
  359.  
  360.                 Data = (ULONG *)Info -> Address;
  361.  
  362.                 ReleaseSemaphore(&MemorySemaphore);
  363.  
  364.                 if(Flags & MEMF_CLEAR)
  365.                 {
  366.                     register ULONG *Memory = Data;
  367.  
  368.                     Size = RoundSize / sizeof(ULONG) - 1;
  369.  
  370.                     do
  371.                         *Memory++ = 0;
  372.                     while(Size--);
  373.                 }
  374.                 else
  375.                 {
  376.                     register ULONG *Memory = Data;
  377.  
  378.                     Size = RoundSize / sizeof(ULONG) - 1;
  379.  
  380.                     do
  381.                         *Memory++ = 0xDEADBEEF;
  382.                     while(Size--);
  383.                 }
  384.  
  385.                 return((APTR)Data);
  386.             }
  387.         }
  388.         else
  389.         {
  390.             ULONG *Data;
  391.  
  392.             Size = (Size + sizeof(ULONG) + 3) & ~3;
  393.  
  394.             if(Data = (ULONG *)AsmAllocPooled(MemoryPool,Size,SysBase))
  395.             {
  396.                 ReleaseSemaphore(&MemorySemaphore);
  397.  
  398.                 *Data++ = Size;
  399.  
  400.                     // Zero the chunk if necessary
  401.  
  402.                 if(Flags & MEMF_CLEAR)
  403.                 {
  404.                     register ULONG *Memory = Data;
  405.  
  406.                     Size = Size / sizeof(ULONG) - 2;
  407.  
  408.                     do
  409.                         *Memory++ = 0;
  410.                     while(Size--);
  411.                 }
  412.  
  413.                 return((APTR)Data);
  414.             }
  415.         }
  416.  
  417.         ReleaseSemaphore(&MemorySemaphore);
  418.     }
  419.  
  420.     return(NULL);
  421. }
  422.